package IO.操作文件;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.DirectoryStream;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.stream.Stream;

import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Exac {
	
	@Test
	void test() throws IOException {
		Logger log = LoggerFactory.getLogger(Exac.class.getName());
		
		Path relative = Paths.get("config", "properties", "user.properties");
		log.info(relative.toString());//config\properties\user.properties  相对路径

//1）首先是final类Paths的两个static方法，如何从一个路径字符串来构造Path对象：
      Path path = Paths.get("C:/", "Xmp");//c:\Xmp
      Path path2 = Paths.get("C:/Xmp");//c:\Xmp
      
      URI u = URI.create("file:///C:/Xmp/dd");        
      Path p = Paths.get(u);//c:\Xmp\dd
      
//2）FileSystems构造：
      Path path3 = FileSystems.getDefault().getPath("C:/", "access.log");//C:\access.log
      System.out.println(path3);
      log.info(path3.toString());
      
//3）File和Path之间的转换，File和URI之间的转换：
      File file = new File("C:/my.ini");
      Path p1 = file.toPath();
      p1.toFile();//C:\my.ini
      file.toURI();//file:/C:/my.ini
      log.info(p1.toFile().toString());
      log.info(file.toURI().toString());
      
//      4）创建一个文件：
//      Path target2 = Paths.get("C:\\mystuff.txt");
//      //Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rw-rw-rw-");
//      //FileAttribute<Set<PosixFilePermission>> attrs = PosixFilePermissions.asFileAttribute(perms);
//      try {
//          if(!Files.exists(target2))
//              Files.createFile(target2);
//      } catch (IOException e) {
//          e.printStackTrace();
//      }
//      windows下不支持PosixFilePermission来指定rwx权限。
      
//5）Files.newBufferedReader读取文件：
      	//input.txt为UTF_8格式，如果选择Charset.forName("GBK")读取，则显示乱码
	  BufferedReader reader = Files.newBufferedReader(Paths.get("d:\\tmp\\input.txt"),StandardCharsets.UTF_8); 
     String str = null;
     while((str = reader.readLine()) != null){  //按行读取 String
         System.out.println(str);
     }
      //可以看到使用 Files.newBufferedReader 远比原来的FileInputStream，然后BufferedReader包装，等操作简单的多了。
      //这里如果指定的字符编码不对，可能会抛出异常 MalformedInputException ，或者读取到了乱码：

//6）文件写操作：

     BufferedWriter writer = Files.newBufferedWriter(Paths.get("d:\\tmp\\input.txt"), StandardCharsets.UTF_8);
     writer.write("测试文件写操作1\n");
     writer.write("测试文件写操作2");
     writer.flush();
     writer.close();

//7）遍历一个文件夹：

      Path dir = Paths.get("f:\\eclipse-workspace");
      try(DirectoryStream<Path> stream = Files.newDirectoryStream(dir)){
          for(Path e : stream){
              System.out.println(e.getFileName());
          }
      }catch(IOException e){
          
      }

      try (Stream<Path> stream = Files.list(Paths.get("C:/"))){
          Iterator<Path> ite = stream.iterator();
          while(ite.hasNext()){
              Path pp = ite.next();
              System.out.println(pp.getFileName());
          }
      } catch (IOException e) {
          e.printStackTrace();
      }
      
      
//      Files.walkFileTree()可以用来遍历每个子目录和文件,SimpleFileVisitor提供了Visitor设计模式提供的四种方法的默认实现： Files.walk(Path path)可以获取
//      指定path下的所有目录结构(文件和目录)
//
//      1. preVisitDirectory()：在访问目录中条目之前在目录上运行。 
//      2. visitFile()：运行目录中的每一个文件。  
//      3. visitFileFailed()：调用无法访问的文件。   
//      4. postVisitDirectory()：在访问目录中条目之后在目录上运行，包括所有的子目录。
//      我们可以实现SimpleFileVisotor重写其中必要的方法来实现自己需求。
      
	}
}
